package thread;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.Vector;
import java.util.concurrent.locks.LockSupport;

/**
 * JDK6中的锁优化：
 *      1：偏向锁：经验优化：JVM发现，大部分情况下，【锁都不存在竞争，并且还是由同一个线程获取锁的】。
 *      2：轻量级锁：经验优化：JVM发现，大部分情况下，【锁不存在竞争，即使有多个线程，那也是A线程先获取锁，释放锁之后，B线程再获取锁】。
 *      3：重量级锁：这就是最终解决【锁存在竞争的情况了】。
 *      4：锁粗化：JIT的一种优化：如果在某段代码中，JIT发现，用户频繁加同一个锁，就会考虑扩大锁的粒度。
 *      5：锁消除：JIT的一种优化：如果在某段代码中，JIT发现，它不可能出现锁的竞争，那么就会将synchronized去除。
 *
 * 在这里面：偏向锁 --》 轻量级锁 --》 重量级锁，这是一个不断复杂的过程。
 * 原因是：偏向锁：只会比较MarkWord的线程id是不是该线程的ID。（采用CAS比较），不会保存一个叫做（Lock Record ID）。
 *  轻量级锁：会记录重入的次数，还会保存一个记录ID（Lock Record ID）。这个ID就是为了以后解锁的时候还原 MarkWord。
 *  重量级锁：会生成一个Monitor对象，里面的owner指向该线程，EntryList保存和该线程竞争的线程。一旦owner释放资源，则会唤醒entryList中的数据，使其竞争资源。
 *      从这三个锁的描述中，就可以看到，他们的复杂程度是逐步增加的。
 *  重量级锁的优化：自旋，如果一个重量级锁，没有获取到资源，那么它会先自旋一段时间，不会阻塞（阻塞涉及到线程上下文的切换和用户态、内核态的切换比较耗时）。
 *      所以才有了【重量级锁的自旋，减少线程上下文的切换】。
 *
 * 偏向锁代码见【TestBiased.java】。
 *
 */
public class JDK6Synchronized {

    /**
     * 锁粗化的案例：
     *      StringBuffer#append方法，就是通过synchronized实现加锁的。
     *      这里JVM发现，可以将多个append方法变成一个append方法，少加锁。
     */
    public String concatString(String s1,String s2,String s3){
        StringBuffer sb=new StringBuffer();
        sb.append(s1);
        sb.append(s2);
        sb.append(s3);
        return sb.toString();
    }
}